#include "iconstyleitemdelegate.h"

#include <QApplication>
#include <QClipboard>
#include <QComboBox>
#include <QDialog>
#include <QFileInfo>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QMimeData>
#include <QMouseEvent>
#include <QMovie>
#include <QPaintEngine>
#include <QPainter>
#include <QPainterPath>
#include <QVBoxLayout>

IconStyleItemDelegate::IconStyleItemDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
    , m_pixmapCache(300 * 1024 * 1024) // 300MB
{
    // 加载一个占位图片，用于非GIF或加载失败时显示
    m_placeholder = QPixmap(":/images/placeholder.png");
}

IconStyleItemDelegate::~IconStyleItemDelegate()
{
    // 清理所有QMovie对象
    qDeleteAll(m_movies);
    m_movies.clear();
}

void IconStyleItemDelegate::setViewVisibleRect(const QRect &rect)
{
    m_visibleRect = rect;

    // 清理不可见项的动画
    QMutableHashIterator<QString, QMovie*> it(m_movies);
    while (it.hasNext()) {
        it.next();
        bool shouldKeep = false;

        // 在实际项目中，这里应该查询哪些index包含这个文件路径
        // 简化实现：假设所有动画都应该保留
        // 实际应用中可以维护一个路径到index的映射
        shouldKeep = true;

        if (!shouldKeep) {
            it.value()->deleteLater();
            it.remove();
        }
    }
}

void IconStyleItemDelegate::setVisibleIndexes(const QModelIndexList &indexes)
{
    QSet<QString> visibleFiles;
    for (const QModelIndex &index : indexes) {
        visibleFiles.insert(index.data(990).toString());
    }

    for (auto it = m_movies.begin(); it != m_movies.end(); ++it) {
        if (visibleFiles.contains(it.key())) {
            if (it.value()->state() == QMovie::NotRunning) {
                it.value()->start();
            }
        } else {
            it.value()->setPaused(true);
        }
    }
}

bool IconStyleItemDelegate::isActuallyGif(const QString &filePath) const
{
    // 检查缓存
    if (m_fileTypeCache.contains(filePath)) {
        return m_fileTypeCache[filePath];
    }

    // 检查文件扩展名和实际内容
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        return false;
    }

    // 读取文件头检查GIF签名
    QByteArray header = file.read(6);
    file.close();

    // GIF文件头可能是"GIF87a"或"GIF89a"
    // return header.startsWith("GIF87a") || header.startsWith("GIF89a");

    bool isGif = header.startsWith("GIF87a") || header.startsWith("GIF89a");
    m_fileTypeCache[filePath] = isGif;
    return isGif;
}

void IconStyleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    qDebug() << "update";
    QString filePath = index.data(990).toString();

    if (filePath.isEmpty()) {
        QStyledItemDelegate::paint(painter, option, index);
        return;
    }

    // 绘制背景
    if (option.state & QStyle::State_Selected) {
        painter->fillRect(option.rect, option.palette.highlight());
    }

    // 处理GIF动画
    // 检查是否在可见区域内
    bool isVisible = option.rect.intersects(m_visibleRect);

    // 检查是否是真正的GIF文件（无论扩展名是什么）
    bool isGif = filePath.endsWith(".gif", Qt::CaseInsensitive) || isActuallyGif(filePath);

    if (isGif) {
        // GIF处理逻辑...
        QMovie *movie = m_movies.value(filePath, nullptr);

        if (isVisible) {
            if (!movie) {
                movie = new QMovie(filePath);
                movie->setCacheMode(QMovie::CacheAll);
                movie->setSpeed(100);
                connect(movie, &QMovie::frameChanged, this, [this, index](){
                    emit const_cast<IconStyleItemDelegate*>(this)->requestUpdate(index);
                });
                m_movies.insert(filePath, movie);
                movie->start();
            }

            QPixmap currentFrame = movie->currentPixmap();
            painter->drawPixmap(option.rect, currentFrame);
        }
        else if (movie) {
            movie->stop();
        }
    }
    // 处理静态图片
    else {
//        QPixmap pixmap(filePath);
//        if (!pixmap.isNull()) {
//            painter->drawPixmap(option.rect, pixmap.scaled(option.rect.size(),
//                                                           Qt::KeepAspectRatio, Qt::SmoothTransformation));
//        } else {
//            painter->drawPixmap(option.rect, m_placeholder.scaled(option.rect.size(),
//                                                                  Qt::KeepAspectRatio, Qt::SmoothTransformation));
//        }

        // 获取设备像素比
        qreal dpr = painter->device()->devicePixelRatioF();

        // 尝试从缓存获取（使用文件路径和显示尺寸作为复合键）
        const QString cacheKey = QString("%1_%2x%3").arg(filePath)
                                     .arg(option.rect.width())
                                     .arg(option.rect.height());

        QPixmap* cachedPixmap = m_pixmapCache.object(cacheKey);
        if (!cachedPixmap) {
            // 缓存未命中 - 从文件加载

//            // 加载图片时考虑DPI缩放
//            QPixmap pixmap;
//            if (!pixmap.load(filePath)) {
//                pixmap = m_placeholder;
//            }

//            if (!pixmap.isNull()) {
//                // 设置适当的设备像素比
//                pixmap.setDevicePixelRatio(devicePixelRatio);

//                // 计算保持宽高比的缩放尺寸
//                QSize scaledSize = option.rect.size();
//                scaledSize *= devicePixelRatio;

//                // 使用高质量缩放
//                QPixmap scaledPixmap = pixmap.scaled(
//                    scaledSize,
//                    Qt::KeepAspectRatio,
//                    Qt::SmoothTransformation
//                    );
//                scaledPixmap.setDevicePixelRatio(devicePixelRatio);

//                // 计算居中绘制位置
//                QPoint drawPos = option.rect.topLeft();
//                if (scaledPixmap.width() / devicePixelRatio < option.rect.width()) {
//                    drawPos.setX(option.rect.x() + (option.rect.width() - scaledPixmap.width() / devicePixelRatio) / 2);
//                }
//                if (scaledPixmap.height() / devicePixelRatio < option.rect.height()) {
//                    drawPos.setY(option.rect.y() + (option.rect.height() - scaledPixmap.height() / devicePixelRatio) / 2);
//                }

//                painter->drawPixmap(drawPos, scaledPixmap);
//            }

            QImageReader reader(filePath);
            reader.setAutoTransform(true); // 自动处理EXIF方向

            // 计算适合高DPI的缩放尺寸
            QSize scaledSize = option.rect.size() * dpr;
            reader.setScaledSize(scaledSize);
            reader.setQuality(100); // 最高质量

            QImage image = reader.read();
            if (!image.isNull()) {
                image.setDevicePixelRatio(dpr);

                // 创建并缓存QPixmap
                cachedPixmap = new QPixmap(QPixmap::fromImage(image));

                // 计算缓存成本（图片内存大小 + 额外开销）
                int cost = image.sizeInBytes() / 1024 + 10; // KB为单位
                m_pixmapCache.insert(cacheKey, cachedPixmap, cost);
            }
        }

        if (cachedPixmap && !cachedPixmap->isNull()) {
            // 计算居中绘制位置
            QSize pixmapSize = cachedPixmap->size() / dpr;
            QRect targetRect(
                option.rect.x() + (option.rect.width() - pixmapSize.width()) / 2,
                option.rect.y() + (option.rect.height() - pixmapSize.height()) / 2,
                pixmapSize.width(),
                pixmapSize.height()
                );

            painter->drawPixmap(targetRect, *cachedPixmap);
        } else {
            // 显示占位图（同样考虑DPI）
            QSize placeholderSize = m_placeholder.size() / m_placeholder.devicePixelRatioF();
            QRect targetRect(
                option.rect.x() + (option.rect.width() - placeholderSize.width()) / 2,
                option.rect.y() + (option.rect.height() - placeholderSize.height()) / 2,
                placeholderSize.width(),
                placeholderSize.height()
                );

            painter->drawPixmap(targetRect, m_placeholder);
        }

    }
}

void IconStyleItemDelegate::paint2(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    painter->save();
    painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
    QPen oldPen = painter->pen();

// 控件区域
    QRectF rect = option.rect;

// 画一个矩形
    const qreal radius = 15;
    QPainterPath path;

    // 此处是圆角的算法(x,y)
    QPointF rl(0, radius);
    QPointF nrl(0, -radius);
    QPointF lr(radius, 0);
    QPointF nlr(-radius,0);

    QPointF rtr = rect.topRight() - QPoint(1,0);
    QPointF rtl = rect.topLeft();
    QPointF rbl = rect.bottomLeft() - QPoint(0,1);
    QPointF rbr = rect.bottomRight() - QPoint(1,1);

    path.moveTo(rtr - lr);          // rtr:rect的顶部右边, 减去 lr(7,0)
    path.lineTo(rtl + lr);          // rtl:rect的顶部左边，加上 lr(7,0)
    path.quadTo(rtl, rtl + rl);     // rtl:rect的顶部左边，y轴相同，加上 rl(0, 7); 绘制一个贝赛尔曲线
    path.lineTo(rbl + nrl);         // rbl:rect的底部左边，加上 nlr(-7,0)
    path.quadTo(rbl, rbl + lr);     // rbl:rect的底部左边，加上 lr(7,0)
    path.lineTo(rbr - lr);          // rbr:rect的底部右边，减去 lr(7,0)
    path.quadTo(rbr, rbr + nrl);    // rbr:rect的底部右边，y轴相同，加上 nrl(0, -7)
    path.lineTo(rtr + rl);          // rtr:rect的顶部右边，加上 rl(0,7)
    path.quadTo(rtr, rtr + nlr);    // rtr:rect的顶部右边，y轴相同，加上 nlr(-7,0)

    // painter->setPen(QPen(Qt::black));
    // painter->fillPath(path, QBrush(QColor("#F4F4F6")));     // 绘制一小块地

    // QFont pfont(family);

    // // 字体名称
    // QRectF rect_title = QRectF(rect.left() + 10, rect.top(), rect.width(), rect.height());
    // QString title = index.data(FontListModel::ContentFontRole).toString();
    // painter->drawText(rect_title, title);
    // painter->setFont(pfont);

    // // 中文说明
    // QString cn;// = index.data(FontListModel::ContentCNRole).toString();
    // cn = "你们这些家伙，就不会写个字体预览工具?";
    // int width_cn = painter->fontMetrics().horizontalAdvance(cn);
    // QRectF rect_cn = QRectF(rect.left() + ((rect.width() - width_cn)/2), rect.top() + 24, rect.width(), rect.height());
    // painter->drawText(rect_cn, cn);

    // // 英文说明
    // QString en;// = index.data(FontListModel::ContentENRole).toString();
    // en = "You guys, you don't write a font preview tool?";
    // en = painter->fontMetrics().elidedText(en, Qt::TextElideMode::ElideRight, rect.width() - 40);
    // int width_en = painter->fontMetrics().horizontalAdvance(en);

    // QRectF rect_en = QRectF(rect.left() + ((rect.width() - width_en)/2), rect.top() + 48, rect.width(), rect.height());
    // painter->drawText(rect_en, en);

    QImage pixmap(index.data(990).toString());
    qDebug() << pixmap.isNull();
    rect.setWidth(option.rect.width() - 2);
    rect.setHeight(option.rect.height() - 2);
    rect.moveCenter(option.rect.center());
    painter->drawImage(rect, pixmap, pixmap.rect());

    painter->restore();

    // delegate->setDevice(painter->device());
    // delegate->repaint();

    // QStyledItemDelegate::paint(painter, option, index);
    // qDebug() << index.data(990).toString() << "Update";
    // if (m_movies->contains(index.data(990).toString())) {
    //     return;
    // }
    // QMovie* movie = new QMovie(index.data(990).toString());
    // m_movies->insert(index.data(990).toString(),movie);

    // QRect rect = option.rect;
    // movie->setScaledSize(QSize(rect.width(), rect.height()));  // 缩放GIF到item的大小


    // auto device = painter->device();
    // connect(movie, &QMovie::frameChanged, this, [movie, device, rect](int frameNumber){
    //     qDebug() << movie->fileName() << "Update";
    //     movie->currentPixmap();
    //     QPainter p(device);
    //     p.setRenderHint(QPainter::SmoothPixmapTransform);
    //     p.setRenderHint(QPainter::Antialiasing);
    //     p.setRenderHint(QPainter::TextAntialiasing);
    //     p.setRenderHint(QPainter::HighQualityAntialiasing);
    //     // p.setRenderHint(QPainter::PixmapFragmentHint);
    //     p.setRenderHint(QPainter::NonCosmeticDefaultPen);
    //     p.drawPixmap(rect, movie->currentPixmap(), rect);
    // });
    // movie->start();
}

QSize IconStyleItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // return QSize(64,64);
    return QPixmap(index.data(990).toString()).scaledToHeight(80).size() + QSize(4,4);
}

void IconStyleItemDelegate::onFrameChanged(int frameNumber)
{
    Q_UNUSED(frameNumber);
    // 当动画帧改变时，请求重绘
    QMovie *movie = qobject_cast<QMovie*>(sender());
    if (movie) {
        // 找到所有使用这个movie的index并更新它们
        for (auto it = m_movies.begin(); it != m_movies.end(); ++it) {
            if (it.value() == movie) {
                emit const_cast<IconStyleItemDelegate*>(this)->sizeHintChanged(
                    QModelIndex()); // 简化实现，实际应该找到具体index
                break;
            }
        }
    }
}

bool IconStyleItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonRelease) {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);

        if (mouseEvent->button() == Qt::RightButton) {
            // 发射右击信号
            emit rightClicked(index, mouseEvent->globalPos());
            return true; // 事件已处理
        }
    }

    return QStyledItemDelegate::editorEvent(event, model, option, index);
}
